<?php
/**
 * MyStuff Export
 *
 * @copyright &copy; 2009 The Open University
 * @author j.platts@open.ac.uk
 * @author
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package convert
 */

class references_convert_mystuff extends format{

    public function __construct(){

    }

    public static function can_import(){
        return false;
    }

    public static function can_export(){
        return true;
    }

    public function import(&$data){
    }

    public static function is_format(&$data){
        return false;
    }

    //Exports to mystuff by calling portfolio/moodel/reference/savetoportfolio.php
    public function export(&$data,$options){
        //if $data is a string turn into xml dom
        if(is_string(&$data)){
            $data=parent::string_to_dom(&$data);
        }

        //check is DOMDocument
        if(!$data instanceOf DOMDocument){
            return false;
        }

        $postarray=array();
        $postarray['formid']=array();
        $postarray['title']=array();
        $postarray['tags']=array();
        $postarray['data']=array();
        $postarray['redirect']='';
        if(isset($options->redirect)){
            $postarray['redirect']=$options->redirect;
        }

        //get reference tags in data
        $reflist=$data->getElementsByTagName('reference');
        $counter=0;
        foreach($reflist as $ref){

            //work out what type of form based on rt (and also add to form arr)
            $rt=$ref->getElementsByTagName('rt')->item(0)->nodeValue;
            $curformid='1000000100';//default
            //check if book
            if(stristr($rt,'book')!==false){
                $curformid='2000000290';
            }else if(stristr($rt,'journal')!==false){
                //journal
                $links=$ref->getElementsByTagName('ul');
                $links2=$ref->getElementsByTagName('lk');
                $curformid='2000000310';
                if($links->length>0 || $links2->length>0){
                    //electronic journal as has web link
                    $curformid='2000000320';
                }
            }elseif(stristr($rt,'web')!==false){
                //webpage
                $curformid='2000000330';
            }else{
                //something else - try and work out roughly what it might be
                //if it's published by OU must be course material...
                $pub=$ref->getElementsByTagName('pb');
                if($pub->length>0){
                    $pub=$pub->item(0)->nodeValue;
                    if(stristr($pub,'open university')!==false){
                        $curformid='2000000340';
                    }
                }
                if($curformid=='1000000100'){
                    //still no match do more checks...?
                    //if it has links make a web page form
                    $links=$ref->getElementsByTagName('ul');
                    $links2=$ref->getElementsByTagName('lk');
                    if($links->length>0 || $links2->length>0){
                        //electronic journal as has web link
                        $curformid='2000000330';
                    }
                }
            }
            unset($rt, $links, $links2, $pub);

            $xmlloc=dirname(__FILE__).'/../../../mod/portfolio/workspaces/';
            if($curformid=='1000000100'){
                $xmlloc.='general/xforms/xml/'.$curformid.'.xml';
            }else{
                $xmlloc.='pdp/xforms/xml/'.$curformid.'.xml';
            }
            //load in xml for that form
            $origformxml=new DOMDocument();
            $origformxml->load($xmlloc);
            $formxml=new DOMDocument('1.0','UTF-8');
            //get the correct bit of xml and add namespace declarations
            $tagname='details';
            if($curformid!='1000000100'){
                $tagname='resource';
            }
            $tagtocopy=$origformxml->getElementsByTagName($tagname)->item(0);
            $basetag=$formxml->importNode($tagtocopy,true);
            unset($tagtocopy, $origformxml);
            //set the fields (again based on each form type)
            //generic
            //title - use t1
            $t1list=$ref->getElementsByTagName('t1');
            if($t1list->length>0){
                $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('t1')->item(0)->nodeValue,$basetag->getElementsByTagName('title'));    
            }       
            //description - use ab(abstract) if if not try no(notes)
            $taglist=$ref->getElementsByTagName('ab');
            if($taglist->length>0){
                $this->addTextToElementName(&$formxml,$taglist->item(0)->nodeValue,$basetag->getElementsByTagName('description'));
            }else{
                $taglist=$ref->getElementsByTagName('no');
                if($taglist->length>0){
                    $this->addTextToElementName(&$formxml,$taglist->item(0)->nodeValue,$basetag->getElementsByTagName('description'));
                }
            }
            unset($taglist);

            //xml tag values based on form template - shared tags
            if($curformid=='2000000290' || $curformid=='2000000310' || $curformid=='2000000320' || $curformid=='2000000330' || $curformid=='2000000340'){
                //shared by books and journals and web page and ou content
                //dcmi:creator - (a1 tags)
                $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('a1'),$basetag->getElementsByTagName('creator'));
                //dcmi:date
                $date=$ref->getElementsByTagName('yr');
                if($date->length>0){
                    $date=$this->prepareDate($date->item(0)->nodeValue);
                    $this->addTextToElementName(&$formxml,$date,$basetag->getElementsByTagName('date'));
                }
                unset($date);
                //dcmi:publisher - pb
                if($curformid!='2000000340'){
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('pb'),$basetag->getElementsByTagName('publisher'));
                }
                if($curformid=='2000000310' || $curformid=='2000000320'){
                    //volume + issue for journals
                    //volume - vo or ed (vo overrides ed if there)
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('ed'),$basetag->getElementsByTagName('volume'));
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('vo'),$basetag->getElementsByTagName('volume'));
                    //issue - is
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('is'),$basetag->getElementsByTagName('issue'));
                }
            }
            //individual cases
            switch($curformid){
                case '2000000290'://book--dcmi:creator,dcmi:date,dcmi:publisher,place_of_publication
                    //place_of_publication - pp
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('pp'),$basetag->getElementsByTagName('place_of_publication'));
                    break;
                case '2000000310'://journal print -<dcmi:creator/><dcmi:publisher/><dcmi:date/><journalTitle/><volume/><issue/><start_page/><other_pages/>
                    //journalTitle - jf
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('jf'),$basetag->getElementsByTagName('journalTitle'));
                    //start_page
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('sp'),$basetag->getElementsByTagName('start_page'));
                    //other_pages (end page?)
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('op'),$basetag->getElementsByTagName('other_pages'));
                    break;
                case '2000000320'://journal electronic - <volume/><issue/><url/><retrieved_date/><electronic_publication_date/>
                    //url - ul or lk (ul overrides lk)
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('lk'),$basetag->getElementsByTagName('url'));
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('ul'),$basetag->getElementsByTagName('url'));
                    $this->cleanLink(&$basetag);
                    //retrieved_date - rd
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('rd'),$basetag->getElementsByTagName('retrieved_date'));
                    //electronic_publication_date - copy dcmi:date
                    $this->addTextToElementName(&$formxml,$basetag->getElementsByTagName('date')->item(0)->nodeValue,$basetag->getElementsByTagName('electronic_publication_date'));
                    break;
                case '2000000330'://web page - <url/><retrieved_date/>
                    //url - ul or lk or ed(refworks xml) (ed overrides ul overrides lk)
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('lk'),$basetag->getElementsByTagName('url'));
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('ul'),$basetag->getElementsByTagName('url'));
                    $eds=$ref->getElementsByTagName('ed');
                    if($eds->length>0){
                        if(strpos($eds->item(0)->nodeValue,'http')!==false){
                            $this->addTextToElementName(&$formxml,$eds,$basetag->getElementsByTagName('url'));
                        }
                    }
                    unset($eds);
                    $this->cleanLink(&$basetag);
                    //retrieved_date - rd
                    $this->addTextToElementName(&$formxml,$ref->getElementsByTagName('rd'),$basetag->getElementsByTagName('retrieved_date'));
                    break;
                case '2000000340';//ou course content - <course_code/><number/><course_title/>

                break;
            }


            $formxml->appendChild($basetag);
            //$out=$formxml->saveXML();
            //add xml string to data posting array
            $postarray['data'][]=$formxml->saveXML();
            unset($formxml);
            //add form id
            $postarray['formid'][]=$curformid;
            //add to the title array based on either titles from options or ref xml title att
            if(isset($options->titles)){
                $postarray['title'][]=$options->titles[$counter];
            }else{
                if($ref->getAttribute('title')!=''){
                    $postarray['title'][]=$ref->getAttribute('title');
                }else{
                    if($t1list->length>0){
                        $postarray['title'][]=$ref->getElementsByTagName('t1')->item(0)->nodeValue;    
                    }
                }
            }
            //add to tags array based on? options (send course ref?)
            $postarray['tags'][$counter]='reference';
            if(isset($options->coursename)){
                $postarray['tags'][$counter].=','.$options->coursename;
            }

            $counter++;
        }
        unset($reflist);
        //implode all postarray arrays so they are strings |#| delimeter
        $postarray['formid']=implode('|#|',$postarray['formid']);
        $postarray['title']=htmlspecialchars(implode('|#|',$postarray['title']),ENT_COMPAT,'UTF-8',false);
        $postarray['tags']=implode('|#|',$postarray['tags']);
        $postarray['data']=implode('|#|',$postarray['data']);

        //deflate data string so is nice and small to post
        $postarray['data']=gzdeflate($postarray['data'],5);

        //call curl
        global $CFG;
        $c = curl_init($CFG->wwwroot.'/mod/portfolio/moodle/reference/saveToPortfolio.php');
        curl_setopt($c, CURLOPT_POST, true);
        curl_setopt($c, CURLOPT_POSTFIELDS, $postarray);
        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($c, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

        if(isset($options->unittest)){
            //for any unit tests - don't access my stuff
            return $postarray;
        }

        $strCookie='';
        foreach($_COOKIE as $cookie=>$cookval){
            if(strpos($cookie,'Debugger')==0)$strCookie.=$cookie.'='.$cookval.';';
        }
        //Not closing the session causes the session to be screwed up when accessing the mystuff page
        session_write_close();

        curl_setopt( $c, CURLOPT_COOKIE, $strCookie );

        $page = curl_exec($c);

        curl_close ($c);

        $success=false;
        //if either false return or detect error from return html show manual submit form
        if($page!=false){
            //work out if there was a success message in the html returned
            $success=strpos($page,'mystuff_success=1');
            if($success!==false){
                $success=true;
            }
        }
        unset($page, $c, $postarray);
        $redirect='';
        if(isset($options->redirect)){
            $redirect=$options->redirect;
        }
        if($redirect==''){
            $redirect=$CFG->wwwroot;
        }
        if($success){
            //else show continue
            echo('<p>'.get_string('refexport_mystuff_success','references').'</p>');
            print_continue($redirect);
        }else{
            echo('<p>'.get_string('refexport_mystuff_fail','references').'</p>');
            print_continue($redirect);
            return false;
        }

        return true; //(always returns as successful)
    }

    /**
     * adds text nodes to all elements in a node list
     * If $text is a node list then equal nodelist nodes are set to equiv value (or created)
     * @param $dom - DOMDoc: dom to create node with
     * @param $text string/Domnodelist: text to add
     * @param $nodelist DOMNodeList: list of nodes to add to
     * @return null
     */
    private function addTextToElementName(&$dom,$text,$nodelist){
        if(is_string($text)){
            $len=$nodelist->length;
            if($len>0){
                for($a=0;$a<$len;$a++){
                    $nodelist->item($a)->appendChild($dom->createTextnode($text));
                }
            }
            return;
        }
        //if you send $text as DomNodeList we add extra elements in $nodelist
        //For example, you might have a list of author tags and only 1 in final doc - so this will create new tags
        if($text instanceof DOMNodeList){
            $len=$nodelist->length;
            $len2=$text->length;
            if($len>0 && $len2>0){
                for($a=0;$a<$len2;$a++){
                    $newtag=$dom->createTextnode($text->item($a)->nodeValue);
                    if($nodelist->item($a)){
                        //matching item in nodelist so populate
                        $nodelist->item($a)->appendChild($newtag);
                    }else{
                        $newnode=$nodelist->item(0)->cloneNode(false);
                        $newnode->appendChild($newtag);
                        //create new item and add after last el of nodelist
                        $nodelist->item($len-1)->parentNode->insertBefore($newnode,$nodelist->item($len-1)->nextSibling);
                    }
                }
            }
        }
    }

    /**
     * Returns the date from the refxml in a format that my stuff supports (2009-07-28)
     * @param $datetext
     * @return string
     */
    private function prepareDate($datetext){
        if($this->isNaN($datetext)){
            if($datetext!=''){
                //not a number remove / and replace with -
                $datetext=str_replace('/','-',$datetext);
                //remove any triple ---
                $datetext=str_replace('---','',$datetext);
                //remove any double
                $datetext=str_replace('--','',$datetext);
                if(strlen($datetext)==4){
                    //assuming only year
                    $datetext.='-01-01';
                }
            }
        }else{
            //is a number
            //if only 4 long assume year only, set date to 1 jan
            if(strlen($datetext)==4){
                return $datetext.'-01-01';
            }
        }
    }

    /**
     * Cleans the link tag in an xml node
     * @param $xml DOMNode
     * @return unknown_type
     */
    private function cleanLink(&$basetag){
        //links from refworks can be multiple ; seperated, if so get first (e.g. .com;http:\\)
        $urls=&$basetag->getElementsByTagName('url');
        if($urls->length>0){
            $colonpos=strpos($urls->item(0)->nodeValue,';http');
            if($colonpos!==false){
                $urls->item(0)->nodeValue=substr($urls->item(0)->nodeValue,0,$colonpos);
            }
        }
    }

}

?>